import os
from flask import Flask, request, jsonify
from flask.json import JSONEncoder
from datetime import datetime, date
import pymysql
from pymysql.converters import escape_string
import traceback

from Devide import devideVideo
from Mp4Change import swapFace_Video
from PhotoChange import changePhoto

app = Flask(__name__)

config = {
            "host": "localhost",
            "user": "root",
            "password": "root",
            "database": "ai-change-face",
            "charset": "utf8"
}


@app.route('/VideoDepart', methods=['POST', 'GET'])  # 获取上传视频的第一帧作为封面
def departVideo():
    vpath = request.args.get("Vpath")  # 视频路径

    cover = devideVideo(vpath)  # 拆分的第一帧图片路径

    payload = []
    content = {'cover': cover}
    payload.append(content)

    return jsonify(payload)  # 返回json


class CustomJSONEncoder(JSONEncoder):  # 调整时间类型的返回格式
    def default(self, obj):
        # if isinstance(obj, datetime):
            # return obj.strftime('%Y-%m-%d %H:%M:%S')
        if isinstance(obj, date):
            return obj.strftime('%Y-%m-%d')
        else:
            return JSONEncoder.default(self, obj)


@app.route('/PictureCheck', methods=['POST', 'GET'])  # 查看用户图片
def selectPicture():
    db = pymysql.connect(**config)  # 连接数据库
    cursor = db.cursor()  # 操作数据库的游标对象

    uid = request.args.get("Userid")  # 用户id

    sql = "select p.pictureid, p.path, p.picturename from picture p join user u on p.userid = u.userid " + \
          "where u.userid = %s"

    try:
        cursor.execute(sql, uid)  # 执行sql语句
        results = cursor.fetchall()  # 得到查询结果

        payload = []
        content = {}
        for result in results:
            content = {'pname': result[2], 'path': result[1], 'pid': result[0]}
            payload.append(content)
            content = {}

        db.commit()  # 提交
        return jsonify(payload)  # 返回json
    except:
        traceback.print_exc()
        db.rollback()  # 错误回滚
        return "查询图片失败"

    db.close()


@app.route('/VideoCheck', methods=['POST', 'GET'])  # 查看用户视频
def selectVideo():
    db = pymysql.connect(**config)  # 连接数据库
    cursor = db.cursor()  # 操作数据库的游标对象

    uid = request.args.get("Userid")  # 用户id

    sql = "select v.videoid, v.path, v.videoname, v.cover from video v join user u on v.userid = u.userid " + \
          "where u.userid = %s"

    try:
        cursor.execute(sql, uid)  # 执行sql语句
        results = cursor.fetchall()  # 得到查询结果

        payload = []
        content = {}
        for result in results:
            content = {'videoname': result[2], 'path': result[1], 'cover': result[3], 'videoid': result[0]}
            payload.append(content)
            content = {}

        db.commit()  # 提交
        return jsonify(payload)  # 返回json
    except:
        traceback.print_exc()
        db.rollback()  # 错误回滚
        return "查询图片失败"

    db.close()


@app.route('/UserInfoCheck', methods=['POST', 'GET'])  # 查找用户信息
def selectUserInfo():
    db = pymysql.connect(**config)  # 连接数据库
    cursor = db.cursor()  # 操作数据库的游标对象

    uid = request.args.get("Userid")  # 用户id
    sql = "select userid, password, nickname, signature, sex, birthday, phone, image from user " \
          "where userid = %s"

    app.json_encoder = CustomJSONEncoder

    try:
        cursor.execute(sql, uid)  # 执行sql语句
        results = cursor.fetchall()  # 得到查询结果

        payload = []
        content = {}
        for result in results:
            content = {'uid': result[0], 'password': result[1], 'nickname': result[2], 'signature': result[3],
                       'sex': result[4], 'birthday': result[5], 'phone': result[6], 'Pixmap': result[7]}
            payload.append(content)
            content = {}

        db.commit()  # 提交
        return jsonify(  payload)  # 返回json
    except:
        traceback.print_exc()
        db.rollback()
        return "查找错误"

    db.close()


@app.route('/UserInfoUpdate', methods=['POST', 'GET'])  # 修改个人信息
def updateUserInfo():
    db = pymysql.connect(**config)  # 连接数据库
    cursor = db.cursor()  # 操作数据库的游标对象

    uid = request.args.get("Userid")  # 用户id
    nickname = request.args.get("Nickname")  # 用户昵称
    signature = request.args.get("Signature")  # 用户签名
    sex = request.args.get("Sex")  # 用户性别
    birthday = request.args.get("Birthday")  # 用户生日
    image = request.args.get("Image")  # 用户头像路径
    phone = request.args.get("Phone")  # 用户电话

    sql = "update user set nickname = %s, signature = %s, sex = %s, birthday = %s, image = %s , phone = %s " \
          "where userid = %s"
    try:
        cursor.execute(sql, (nickname, signature, sex, birthday, image, phone, uid))  # 执行SQL语句

        db.commit()
        return "修改成功！"
    except:
        traceback.print_exc()
        db.rollback()  # 错误回滚
        return "修改失败"

    db.close()


@app.route('/PasswordUpdate', methods=['POST', 'GET'])  # 修改密码
def updateUserPwd():
    db = pymysql.connect(**config)  # 连接数据库
    cursor = db.cursor()  # 操作数据库的游标对象

    uid = request.args.get("Userid")  # 用户id
    password = request.args.get("Password")  # 用户新密码

    sql = "update user set password = %s where userid = %s"

    try:
        cursor.execute(sql, (password, uid))  # 执行SQL语句

        db.commit()  # 提交
        return "修改成功！"
    except:
        traceback.print_exc()
        db.rollback()  # 错误回滚
        return "修改失败"

    db.close()


@app.route('/Login', methods=['POST', 'GET'])  # 登录
def getLoginRequest():
    db = pymysql.connect(**config)  # 连接数据库
    cursor = db.cursor()  # 操作数据库的游标对象

    uid = request.args.get('Userid')  # 用户id
    pwd = request.args.get('Password')  # 用户密码

    sql = "select * from user where userid = %s and password = %s"
    try:
        cursor.execute(sql, (uid, pwd))
        results = cursor.fetchall()  # 执行sql语句获得结果

        print("登录请求查找到用户数：", len(results))
        db.commit()  # 提交

        if len(results) == 1:
            return "登录成功"
        else:
            return "不存在此用户，登录失败"
    except:
        traceback.print_exc()
        db.rollback()  # 错误回滚
        return "登录失败"

    db.close()


@app.route("/Register", methods=['POST', 'GET'])  # 注册
def getRigiestRequest():
    db = pymysql.connect(**config)  # 连接数据库
    cursor = db.cursor()  # 操作数据库的游标对象

    uid = request.args.get('Userid')  # 用户id
    password = request.args.get('Password')  # 用户密码
    nickname = request.args.get('Nickname')  # 用户昵称

    if not os.path.exists("D:/" + uid + "/video"):  # 建立用户文件夹
        os.makedirs("D:/" + uid + "/video")
    if not os.path.exists("D:/" + uid + "/picture"):
        os.makedirs("D:/" + uid + "/picture")

    sql = "insert into user(userid, password, nickname) values(%s, %s, %s)"

    try:
        cursor.execute(sql, (uid, password, nickname))  # 执行SQL语句

        db.commit()  # 提交

        return "注册成功"
    except:
        db.rollback()  # 错误回滚
        return "用户名已存在，注册失败"

    db.close()


@app.route('/VideoUpdate', methods=['POST', 'GET'])  # 修改视频名
def updateVideo():
    db = pymysql.connect(**config)  # 连接数据库
    cursor = db.cursor()  # 操作数据库的游标对象

    vid = request.args.get("Videoid")  # 视频id
    vname = request.args.get("Videoname")  # 视频新名字

    sql = "update video set videoname = %s where videoid = %s"

    try:
        cursor.execute(sql, (vname, vid))  # 执行SQL语句

        db.commit()  # 提交
        return "视频修改成功！"
    except:
        traceback.print_exc()
        db.rollback()  # 错误回滚
        return "视频修改失败"

    db.close()


@app.route('/PictureUpdate', methods=['POST', 'GET'])  # 修改图片名
def updatePicture():
    db = pymysql.connect(**config)  # 连接数据库
    cursor = db.cursor()  # 操作数据库的游标对象

    pid = request.args.get("Pictureid")  # 图片id
    pname = request.args.get("Picturename")  # 图片新名字

    sql = "update picture set picturename = %s where pictureid = %s"

    try:
        cursor.execute(sql, (pname, pid))  # 执行SQL语句

        db.commit()  # 提交
        return "图片修改成功！"
    except:
        traceback.print_exc()
        db.rollback()  # 错误回滚
        return "图片修改失败"

    db.close()


@app.route('/VideoDelete', methods=['POST', 'GET'])  # 删除视频
def deleteVideo():
    db = pymysql.connect(**config)  # 连接数据库
    cursor = db.cursor()  # 操作数据库的游标对象

    vid = request.args.get("Videoid")  # 视频id
    print(vid)
    sql = "delete from video where videoid = %s"

    try:
        cursor.execute(sql, vid)  # 执行SQL语句

        db.commit()  # 提交
        return "视频删除成功"
    except:
        traceback.print_exc()
        db.rollback()  # 错误回滚
        return "视频删除失败"

    db.close()


@app.route('/PictureDelete', methods=['POST', 'GET'])  # 删除图片
def deletePicture():
    db = pymysql.connect(**config)  # 连接数据库
    cursor = db.cursor()  # 操作数据库的游标对象

    pid = request.args.get("Pictureid")  # 视频id

    sql = "delete from picture where pictureid = %s"

    try:
        cursor.execute(sql, pid)  # 执行SQL语句

        db.commit()  # 提交
        return "图片删除成功"
    except:
        traceback.print_exc()
        db.rollback()  # 错误回滚
        return "图片删除失败"

    db.close()


@app.route('/PhotoFaceSwap', methods=['POST', 'GET'])  # 图片换脸，保存换脸后图片
def swapPhoto():
    db = pymysql.connect(**config)  # 连接数据库
    cursor = db.cursor()  # 操作数据库的游标对象

    uid = request.args.get("Userid")  # 用户id
    path_goal = request.args.get("Goal")  # 目标图片路径
    path_origin = request.args.get("Origin")  # 初始目标路径

    out = changePhoto(path_goal, path_origin, uid)  # 换脸后图片路径

    sql = "insert into `picture`(`userid`, `path`) values(%s, %s)"
    try:  # 执行SQL语句
        cursor.execute(sql, (uid, out))
        db.commit()  # 提交

        payload = []
        content = {'path': out}
        payload.append(content)

        return jsonify(payload)  # 返回json
    except:
        traceback.print_exc()
        db.rollback()  # 错误回滚
        return "图片保存失败"

    db.close()


@app.route('/VideoFaceSwap', methods=['POST', 'GET'])  # 视频实时换脸，保存换脸后视频
def swapVideo():
    db = pymysql.connect(**config)  # 连接数据库
    cursor = db.cursor()  # 操作数据库的游标对象

    uid = request.args.get("Userid")  # 用户id
    ppath = request.args.get("Ppath")  # 图片路径
    vpath = request.args.get("Vpath")  # 视频路径

    out = swapFace_Video(ppath, vpath, uid)  # 换脸后视频路径
    cover = "./test/Mp4Change/input/convert/1.jpg"

    sql = "insert into video(path, userid, cover) values(%s, %s, %s)"
    try:  # 执行SQL语句
        cursor.execute(sql, (out, uid, cover))
        db.commit()  # 提交

        payload = []
        content = {'path': out, 'cover': cover}
        payload.append(content)

        return jsonify(payload)  # 返回json
    except:
        traceback.print_exc()
        db.rollback()  # 错误回滚
        return "视频保存失败"

    db.close()


@app.route('/StyleTransfer', methods=['POST', 'GET'])  # 风格迁移
def changeStyle():
    db = pymysql.connect(**config)  # 连接数据库
    cursor = db.cursor()  # 操作数据库的游标对象

    uid = request.args.get("Userid")  # 用户id
    path_goal = request.args.get("Goal")  # 风格目标图片路径
    path_origin = request.args.get("Origin")  # 原始图片路径

    os_str = "python StyleTransfer.py " + path_goal + " " + path_origin + " " + uid
    f = os.popen(os_str, 'r')  # 运行风格迁移python脚本
    res = f.readlines()  # 获取显示值

    out = res[len(res)-1]  # 迁移后图片路径
    f.close()

    sql = "insert into picture(path, userid) values(%s, %s)"
    try:  # 执行SQL语句
        cursor.execute(sql, (out, uid))
        db.commit()  # 提交

        payload = []
        content = {'path': out}
        payload.append(content)

        return jsonify(payload)  # 返回json
    except:
        traceback.print_exc()
        db.rollback()  # 错误回滚
        return "风格迁移失败"

    db.close()


@app.route('/FaceSwap', methods=['POST', 'GET'])  # 非实时视频换脸
def swapFace():
    os_str = "python faceswap-pytorch/train.py"
    os.system(os_str)
    return "换脸结束"


@app.route('/PhotoCartoon', methods=['POST', 'GET'])  # 图片动漫化
def animatePhoto():
    db = pymysql.connect(**config)  # 连接数据库
    cursor = db.cursor()  # 操作数据库的游标对象

    uid = request.args.get("Userid")  # 用户id
    path = request.args.get("Path")  # 要动漫化的图片路径

    os_str = "python ./animegan2-pytorch-main/test.py --uid " + uid + " --input " + path
    f = os.popen(os_str, 'r')
    # sys.argv[1]   sys.argv[2]
    res = f.readlines()
    print(res)

    out = res[len(res)-2]  # 动漫化后图片路径
    out = out[:-1]
    f.close()

    sql = "insert into picture(userid, path) values (%s, %s)"
    try:  # 执行SQL语句
        cursor.execute(sql, (uid, out))
        db.commit()  # 提交

        payload = []
        content = {'path': out}
        payload.append(content)

        return jsonify(payload)  # 返回json
    except:
        traceback.print_exc()
        db.rollback()  # 错误回滚
        return "图片动漫化失败"

    db.close()


@app.route('/PhotoColour', methods=['POST', 'GET'])  # 黑白图片彩色化
def colourPhoto():
    db = pymysql.connect(**config)  # 连接数据库
    cursor = db.cursor()  # 操作数据库的游标对象

    uid = request.args.get("Userid")  # 用户id
    path = request.args.get("Path")  # 要彩色化化的图片路径

    os_str = "python run.py " + path + " " + uid
    f = os.popen(os_str, 'r')
    res = f.readlines()

    out = res[len(res)-2]  # 彩色化后图片路径
    out = out[:-1]
    f.close()

    sql = "insert into picture(userid, path) values (%s, %s)"
    try:  # 执行SQL语句
        cursor.execute(sql, (uid, out))
        db.commit()  # 提交

        payload = []
        content = {'path': out}
        payload.append(content)

        return jsonify(payload)  # 返回json
    except:
        traceback.print_exc()
        db.rollback()  # 错误回滚
        return "图片黑白化失败"
    db.close()


@app.route('/FaceBeauty', methods=['POST', 'GET'])  # 美颜
def beautyFace():
    os_str = "python AIMakeup-master/Ui_MakupGUI.py"
    os.system(os_str)
    return "美颜结束"


@app.route('/FaceRecognition', methods=['POST', 'GET'])  # 人脸匹配
def recognizeFace():
    path_known = request.args.get("Known")  # 已知人脸路径
    path_detect = request.args.get("Detect")  # 要匹配的图片路径

    os_str = "python FinePhotoOne.py " + path_known + " " + path_detect
    f = os.popen(os_str, 'r')  # 运行人脸匹配python脚本
    f.close()

    payload = []
    content = {'path': "E:/Python/FinalAIface/test/FinePhotoOne/output/output.jpg"}
    payload.append(content)

    return jsonify(payload)  # 返回json


if __name__ == '__main__':
    app.run()
